package com.itheima.controller;

import ch.qos.logback.classic.pattern.LineOfCallerConverter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.conmmon.BaseContext;
import com.itheima.conmmon.CustomException;
import com.itheima.conmmon.R;
import com.itheima.domain.*;
import com.itheima.dto.DishDto;
import com.itheima.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Base64Util;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author liwanhu
 * @datetime 2021/10/27 14:27
 */
@RestController
@RequestMapping("dish")
@Slf4j
public class DishController {
    @Autowired
    private DishService dishService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private SetMealService setMealService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加菜品,将信息添加到菜品表Dish,将口味信息添加到口味表Dish_flavor
     *
     * @param dishDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto) {
        dishService.saveWithFlavor(dishDto);
        //清理redis缓存
        String key = "Dish_" + dishDto.getCategoryId() + "_1";
        log.info(key);
        redisTemplate.delete(key);
        return R.success("添加菜品数据成功");
    }

    /**
     * 分页查询
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("page")
    public R<Page> page(int page, int pageSize, String name) {
        //构造分页构造器
        Page<Dish> pageInfo = new Page<>(page, pageSize);
        Page<DishDto> dishDtoPage = new Page<>();
        //构造条件查询
        QueryWrapper<Dish> qw = new QueryWrapper<>();
        qw.like(name != null, "name", name);
        qw.orderByDesc("update_time");
        dishService.page(pageInfo, qw);

        //将分页内容拷贝到DishDto中
        BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");
        List<Dish> records = pageInfo.getRecords();
        //遍历records对象
        List<DishDto> list = records.stream().map((item) -> {
            //获取records对象中的分类ID
            Long categoryId = item.getCategoryId();
            //创建空的DishDto对象
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            //获取分类表中的数据
            Category category = categoryService.getById(categoryId);
            if (category != null) {
                //获取分类的名称
                String names = category.getName();
                //将获取到的分类名称存到CategoryName对象中
                dishDto.setCategoryName(names);
            }
            return dishDto;
        }).collect(Collectors.toList());
        //将重新获取的值set到dishDtoPage对象中,将数据返回到浏览器
        dishDtoPage.setRecords(list);

        return R.success(dishDtoPage);
    }

    /**
     * 根据id查询菜品,和菜品的口味
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<DishDto> get(@PathVariable Long id) {
        DishDto dishWithFlavor = dishService.getDishWithFlavor(id);
        return R.success(dishWithFlavor);
    }

    /**
     * 修改菜品
     *
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto) {
        dishService.updateWithFlavor(dishDto);
        //删除所有在redis缓存中的菜品数据
        String key = "Dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);
        return R.success("修改数据成功");
    }

    /**
     * 查询通过菜品分类查询菜品信息
     *
     * @param //dish
     * @return
     */
    @GetMapping("list")
    public R<List<DishDto>> list(Dish dish) {
        //获取的菜品集合
        List<DishDto> dishDtoList =null;
        //创建需要存入redis非关系型数据库中的对象
        String key = "Dish_"+dish.getCategoryId()+"_"+dish.getStatus();
        //从redis缓存中获取菜品数据
        dishDtoList  = (List<DishDto>) redisTemplate.opsForValue().get(key);
        if (dishDtoList !=null){
            return R.success(dishDtoList);
        }
        /**
         * 如果查询的缓存数据是空的话则去查数据库表中的数据
         */
        //创建条件构造
        QueryWrapper<Dish> qw = new QueryWrapper<>();
        //查询菜品对应的菜品类型
        qw.eq(dish.getCategoryId() != null, "category_id", dish.getCategoryId());
        qw.orderByAsc("sort").orderByDesc("update_time");
        //菜品分类对应的菜品
        List<Dish> list = dishService.list(qw);

        dishDtoList = list.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if (category != null) {
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            //获取当前菜品的ID
            Long dishId = item.getId();
            //菜品对应的口味
            QueryWrapper<DishFlavor> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("dish_id", dishId);
            //查询出口味集合
            List<DishFlavor> flavorsList = dishFlavorService.list(queryWrapper);
            //将口味集合存到dto类中
            dishDto.setFlavors(flavorsList);
            return dishDto;
        }).collect(Collectors.toList());
        //将从数据库中查询的数据存入redis缓存中
        redisTemplate.opsForValue().set(key,dishDtoList,60, TimeUnit.MINUTES);
        return R.success(dishDtoList);
    }

    /**
     * 实战第一天
     * 批量删除菜品
     *
     * @param ids
     * @return
     */
    @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids) {
        log.info(ids.toString());
        dishService.removeDish(ids);
        //String key = "Dish_";
       /* for (Long id : ids) {
            Dish byId = dishService.getById(id);
            Long categoryId = byId.getCategoryId();
            Category category = categoryService.getById(categoryId);
            Long id1 = category.getId();
            String key = "Dish_"+id1+"_1";
            redisTemplate.delete(key);
        }*/
        return R.success("删除成功");
    }

    /**
     * 实战第一天
     * 菜品的状态的修改
     *
     * @param status
     * @param ids
     * @return
     */
    @PostMapping("status/{status}")
    public R<String> status(@PathVariable Integer status, @RequestParam List<Long> ids) {
        for (int i = 0; i < ids.size(); i++) {
            /*Dish dish = new Dish();
            dish.setStatus(status);
            dish.setId(ids.get(i));*/
            UpdateWrapper<Dish> dishUpdateWrapper = new UpdateWrapper<>();
            dishUpdateWrapper.eq("id", ids.get(i));
            dishUpdateWrapper.set("status", status);

            //查询在不在套餐中存在
            QueryWrapper<SetmealDish> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("dish_id", ids.get(i));

            //获取菜品的数量
            List<SetmealDish> list = setmealDishService.list(queryWrapper);
            //如果前端传过来的status状态是1的话,直接修改装填
            if (status == 1) {
                dishService.update(dishUpdateWrapper);
            } else {
                //判断菜品存在不存在与套餐中,不存在就修改
                if (list.size() == 0) {
                    dishService.update(dishUpdateWrapper);
                }
                //存在时在判断套餐的状态
                for (SetmealDish setmealDish : list) {
                    //通过setmealDish表数据,获取套餐id
                    Long setmealId = setmealDish.getSetmealId();
                    //获取套餐的信息
                    Setmeal setmeal = setMealService.getById(setmealId);
                    //获取套餐状态
                    Integer statusNumber = setmeal.getStatus();
                    //判断套餐的状态
                    //!=0是套餐正在起售中,菜品不可以被停售
                    if (statusNumber != 0) {
                        throw new CustomException("套餐正在销售中,不能修改套餐中的菜品状态");
                    }
                }
            }
            dishService.update(dishUpdateWrapper);
        }
        return R.success("修改状态成功");
    }
}
